package com.neucollege.system.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.JWTValidator;
import cn.hutool.jwt.signers.JWTSigner;
import com.neucollege.system.constant.MessageConstant;
import com.neucollege.system.domain.pojo.Admin;
import com.neucollege.system.domain.pojo.Supervisor;
import com.neucollege.system.domain.pojo.Worker;
import com.neucollege.system.exception.JWTException;
import com.neucollege.system.exception.UserNotLoginExecption;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Component
@RequiredArgsConstructor
public class JwtUtils {

    private final KeyUtils keyUtils;
    private final Long validTime = 1000*60*60*24L; //过期时间为24h

    public Map<String ,Object> headers(){
        HashMap<String, Object> heads = new HashMap<>();
        heads.put("validTime", System.currentTimeMillis() + validTime);
        return heads;
    }
    /**
     * 生成监督员对象的token
     * 存入id ， realName ， phone字段
     */
    public String ofSupervisor(Supervisor supervisor) throws IOException, NoSuchAlgorithmException, ClassNotFoundException {
        Map<String , Object> payloads = new HashMap<>();
        payloads.put("id",supervisor.getId());
        payloads.put("realName",supervisor.getRealName());
        payloads.put("phone",supervisor.getPhone());
        return JWTUtil.createToken(headers(),payloads,keyUtils.getPrivateSigner());
    }

    /**
     * 生成管理员对象token
     * 存入id字段
     */
    public String ofAdmin(Admin admin) throws IOException, NoSuchAlgorithmException, ClassNotFoundException {
        Map<String , Object> payloads = new HashMap<>();
        payloads.put("id",admin.getId());
        return JWTUtil.createToken(headers(),payloads,keyUtils.getPrivateSigner());
    }

    /**
     * 生成网格员对象token
     * 存入id ， name字段
     */
    public String ofWorker(Worker worker) throws IOException, NoSuchAlgorithmException, ClassNotFoundException {
        Map<String , Object> payloads = new HashMap<>();
        payloads.put("id",worker.getId());
        payloads.put("name",worker.getName());
        return JWTUtil.createToken(headers(),payloads,keyUtils.getPrivateSigner());
    }


    /**
     * 校验JWT令牌
     */
    private JWT parse(String token) throws IOException, NoSuchAlgorithmException, ClassNotFoundException {
        if(Objects.isNull(token) || token.isBlank()){
            throw new UserNotLoginExecption(MessageConstant.USER_NOT_LOGIN);
        }
        JWT jwt = JWTUtil.parseToken(token);
        JWTSigner rsa = keyUtils.getPublicSigner();

        JWTValidator.of(token).validateDate(DateUtil.date());
        if(JWTUtil.verify(token,rsa)){
            throw new JWTException(MessageConstant.WRONG_SINGER);
        }
        if(Long.parseLong(jwt.getHeader("validTime").toString()) < System.currentTimeMillis()){
            throw new UserNotLoginExecption(MessageConstant.USER_TIME_OUT);
        }
        return jwt;
    }

    /**
     * 将token令牌转换为Supervisor实体类
     * 存有id ， realName ， phone字段
     */
    public Supervisor parseSupervisor(String token) throws IOException, NoSuchAlgorithmException, ClassNotFoundException {
        return JSONUtil.toBean(parse(token).getPayloads(), Supervisor.class);
    }

    /**
     * 将token转换为管理员实体类
     * 存有id字段
     */
    public Admin parseAdmin(String token) throws IOException, NoSuchAlgorithmException, ClassNotFoundException {
        return JSONUtil.toBean(parse(token).getPayloads(),Admin.class);
    }

    /**
     * 将token转换为网格员实体类
     * 存有id ， name字段
     */
    public Worker parseWorker(String token) throws IOException, NoSuchAlgorithmException, ClassNotFoundException {
        return JSONUtil.toBean(parse(token).getPayloads(), Worker.class);
    }
}
